package com.bkhech.spring.security.example.service.impl;

import com.bkhech.spring.security.example.accesstoken.oauth2.OAuth2TokenApi;
import com.bkhech.spring.security.example.accesstoken.oauth2.dto.OAuth2AccessTokenCreateReqDto;
import com.bkhech.spring.security.example.accesstoken.oauth2.dto.OAuth2AccessTokenRespDto;
import com.bkhech.spring.security.example.domain.AuthLoginRespVo;
import com.bkhech.spring.security.example.domain.dao.UserInfo;
import com.bkhech.spring.security.example.service.AuthService;
import com.bkhech.spring.security.example.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * Auth Service 实现类
 *
 * @author guowm
 * @date 2023/2/1
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AuthServiceImpl implements AuthService {
    final UserService userService;
    final OAuth2TokenApi oAuth2TokenApi;

    @Override
    public UserInfo authenticate(String username, String password) {
        final UserInfo userInfo = userService.getUserByUsername(username);
        if (Objects.isNull(userInfo)) {
            System.out.println("登录失败，用户名错误");
            throw new BadCredentialsException("用户名密码错误");
        }

        if (!userService.isPasswordMatch(password, userInfo.getPassword())) {
            System.out.println("登录失败，密码错误");
            throw new BadCredentialsException("用户名密码错误");
        }

        if (!userInfo.getEnabled()) {
            System.out.println("登录失败，该用户已禁用");
            throw new BadCredentialsException("用户名密码错误");
        }
        return userInfo;
    }

    @Override
    public AuthLoginRespVo login(String username, String passwd) {
        // 使用账号密码，进行登录
        final UserInfo user = this.authenticate(username, passwd);
        System.out.println("登录成功");
        // 创建 Token 令牌
        return createTokenAfterLoginSuccess(user.getId());
    }

    private AuthLoginRespVo createTokenAfterLoginSuccess(Long userId) {
        final OAuth2AccessTokenCreateReqDto reqDto = new OAuth2AccessTokenCreateReqDto();
        reqDto.setUserId(userId);
        reqDto.setClientId("default");
        final OAuth2AccessTokenRespDto oAuth2AccessTokenDto = oAuth2TokenApi.createAccessToken(reqDto);
        return AuthLoginRespVo.builder()
                .userId(userId)
                .accessToken(oAuth2AccessTokenDto.getAccessToken())
                .refreshToken(oAuth2AccessTokenDto.getRefreshToken())
                .expiresTime(oAuth2AccessTokenDto.getExpiresTime())
                .build();
    }
}
